﻿using A.M.ETO;
using A.M.Storage.I_Infrastruecure;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace A.M.Storage.Infrastruecure
{
    public class BaseRepository<T, K> : SimpleClient<T>, IBaseRepository<T, K> where T : class, new()
    {
        private readonly ISqlSugarClient _client;
        public BaseRepository(ISqlSugarClient client)
        {
            _client = client;
        }
        /// <summary>
        /// 单添加
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public int AddInfor(T t)
        {
            var res = _client.Insertable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 单添加_异步
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public async Task<int> AddInfor_Async(T t)
        {
            try
            {
            var res = await _client.Insertable(t).ExecuteCommandAsync();
            return res;

            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public int AddInfor_Batch(List<T> t)
        {
            var res = _client.Insertable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 批量添加_异步
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public async Task<int> AddInfor_Batch_Async(List<T> t)
        {
            try
            {
                var res = await _client.Insertable(t).ExecuteCommandAsync();
                return res;
            }
            catch (Exception)
            {

                throw;
            }

        }
        /// <summary>
        /// 单删除
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public int DelInfor(T t)
        {
            var res = _client.Deleteable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 单删除_异步
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public async Task<int> DelInfor_Async(T t)
        {
            var res = await _client.Deleteable(t).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public int DelInfor_Batch(List<T> t)
        {
            var res = _client.Deleteable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 批量删除_异步
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public Task<int> DelInfor_Batch_Async(List<T> t)
        {
            var res = _client.Deleteable(t).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 事务
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public bool ExecuteTrans(Action<ISqlSugarClient> action)
        {
            bool success = false;
            try
            {
                _client.Ado.UseTran(() =>
                {
                    action(_client);
                });
                success = true;
            }
            catch (Exception ex)
            {
                // 异常处理
                success = false;
            }
            return success;
        }
        /// <summary>
        /// 单修改
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public int UpdInfor(T t)
        {
            var res = _client.Updateable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 单修改_异步
        /// </summary>
        /// <param name="t">对象</param>
        /// <returns>受影响行数</returns>
        public async Task<int> UpdInfor_Async(T t)
        {
            var res = await _client.Updateable(t).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public int UpdInfor_Batch(List<T> t)
        {
            var res = _client.Updateable(t).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 批量修改_异步
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>受影响行数</returns>
        public async Task<int> UpdInfor_Batch_Async(List<T> t)
        {
            var res = await _client.Updateable(t).ExecuteCommandAsync();
            return res;
        }

        /// <summary>
        /// 无条件查询
        /// </summary>
        /// <returns>List<T></returns>
        public List<T> GetShowInforOrder(Expression<Func<T, object>> orderInfor)
        {
            var list = _client.Queryable<T>().OrderByDescending(orderInfor).ToList();
            return list;
        }

        public List<T> GetShowInforOrder(Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            var list = _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor).ToList();
            return list;
        }

        public PageETO<T> GetShowInforOrder(int pageSize, int pageIndex, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = _client.Queryable<T>().OrderByDescending(orderInfor).ToList();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public PageETO<T> GetShowInforOrder(int pageSize, int pageIndex, Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor).ToList();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public T GetShowObj(Expression<Func<T, bool>> exception)
        {
            var res = _client.Queryable<T>().First(exception);
            return res;
        }

        public async Task<List<T>> GetShowInforAsyncOrder(Expression<Func<T, object>> orderInfor)
        {
            var list = await _client.Queryable<T>().OrderByDescending(orderInfor).ToListAsync();
            return list;
        }

        public async Task<List<T>> GetShowInforAsyncOrder(Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            var list = await _client.Queryable<T>().OrderByDescending(orderInfor).Where(exception).ToListAsync();
            return list;
        }

        public async Task<PageETO<T>> GetShowInforAsyncOrder(int pageSize, int pageIndex, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = await _client.Queryable<T>().OrderByDescending(orderInfor).ToListAsync();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public async Task<PageETO<T>> GetShowInforAsyncOrder(int pageSize, int pageIndex, Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            try
            {
                PageETO<T> pageETO = new PageETO<T>();
                var list = await _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor).ToListAsync();
                pageETO.TotalCount = list.Count();
                pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
                pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                return pageETO;
            }
            catch (Exception)
            {

                throw;
            }
            
        }

        public async Task<T> GetShowObjAsync(Expression<Func<T, bool>> exception)
        {
            var res = await _client.Queryable<T>().FirstAsync(exception);
            return res;
        }

        public ISugarQueryable<T> GetShowQueryableOrder(Expression<Func<T, object>> orderInfor)
        {

            var queryable = _client.Queryable<T>().OrderByDescending(orderInfor);
            return queryable;
        }

        public ISugarQueryable<T> GetShowQueryableOrder(Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            // 获取 ISugarQueryable<T> 对象
            var sugarQueryable = _client.Queryable<T>().OrderByDescending(orderInfor).Where(exception);

            return sugarQueryable;
        }

        public PageETO<T> GetShowQueryableOrder(int pageSize, int pageIndex, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = _client.Queryable<T>().OrderByDescending(orderInfor);
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public PageETO<T> GetShowQueryableOrder(int pageSize, int pageIndex, Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor);
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }


        public async Task<ISugarQueryable<T>> GetShowQueryableAsyncOrder(Expression<Func<T, object>> orderInfor)
        {
            var sugarQueryable = await Task.Run(() => _client.Queryable<T>().OrderByDescending(orderInfor));
            return sugarQueryable;
        }

        public async Task<ISugarQueryable<T>> GetShowQueryableAsyncOrder(Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            var sugarQueryable = await Task.Run(() => _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor));
            return sugarQueryable;
        }

        public async Task<PageETO<T>> GetShowQueryableAsyncOrder(int pageSize, int pageIndex, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = await Task.Run(() => _client.Queryable<T>().OrderByDescending(orderInfor));
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public async Task<PageETO<T>> GetShowQueryableAsyncOrder(int pageSize, int pageIndex, Expression<Func<T, bool>> exception, Expression<Func<T, object>> orderInfor)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = await Task.Run(() => _client.Queryable<T>().Where(exception).OrderByDescending(orderInfor));
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public PageETO<T> GetPageShow(int pageSize, int pageIndex, List<T> values)
        {
            PageETO<T> pageETO = new PageETO<T>();
            pageETO.TotalCount = values.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(values.Count() * 1.0 / pageSize));
            pageETO.Data = values.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        
        public void BeginTranInfor()
        {
            _client.Ado.BeginTran();
        }

        public void CommitTranInfor()
        {
            _client.Ado.CommitTran();
        }

        public void RollbackTranInfor()
        {
            _client.Ado.RollbackTran();
        }

        /// <summary>
        /// 无条件查询
        /// </summary>
        /// <returns>List<T></returns>
        public List<T> GetShowInfor()
        {
            var list = _client.Queryable<T>().ToList();
            return list;
        }

        public List<T> GetShowInfor(Expression<Func<T, bool>> exception)
        {
            var list = _client.Queryable<T>().Where(exception).ToList();
            return list;
        }

        public PageETO<T> GetShowInfor(int pageSize, int pageIndex)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = _client.Queryable<T>().ToList();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public PageETO<T> GetShowInfor(int pageSize, int pageIndex, Expression<Func<T, bool>> exception)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = _client.Queryable<T>().Where(exception).ToList();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public async Task<List<T>> GetShowInforAsync()
        {
            var list = await _client.Queryable<T>().ToListAsync();
            return list;
        }

        public async Task<List<T>> GetShowInforAsync(Expression<Func<T, bool>> exception)
        {
            var list = await _client.Queryable<T>().Where(exception).ToListAsync();
            return list;
        }

        public async Task<PageETO<T>> GetShowInforAsync(int pageSize, int pageIndex)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var list = await _client.Queryable<T>().ToListAsync();
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
            pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public async Task<PageETO<T>> GetShowInforAsync(int pageSize, int pageIndex, Expression<Func<T, bool>> exception)
        {
            try
            {
                PageETO<T> pageETO = new PageETO<T>();
                var list = await _client.Queryable<T>().Where(exception).ToListAsync();
                pageETO.TotalCount = list.Count();
                pageETO.PageCount = Convert.ToInt32(Math.Ceiling(list.Count() * 1.0 / pageSize));
                pageETO.Data = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                return pageETO;
            }
            catch (Exception)
            {

                throw;
            }

        }

        public ISugarQueryable<T> GetShowQueryable()
        {

            var queryable = _client.Queryable<T>();
            return queryable;
        }

        public ISugarQueryable<T> GetShowQueryable(Expression<Func<T, bool>> exception)
        {
            // 获取 ISugarQueryable<T> 对象
            var sugarQueryable = _client.Queryable<T>().Where(exception);

            return sugarQueryable;
        }

        public PageETO<T> GetShowQueryable(int pageSize, int pageIndex)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = _client.Queryable<T>();
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public PageETO<T> GetShowQueryable(int pageSize, int pageIndex, Expression<Func<T, bool>> exception)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = _client.Queryable<T>().Where(exception);
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }


        public async Task<ISugarQueryable<T>> GetShowQueryableAsync()
        {
            var sugarQueryable = await Task.Run(() => _client.Queryable<T>());
            return sugarQueryable;
        }

        public async Task<ISugarQueryable<T>> GetShowQueryableAsync(Expression<Func<T, bool>> exception)
        {
            var sugarQueryable = await Task.Run(() => _client.Queryable<T>().Where(exception));
            return sugarQueryable;
        }

        public async Task<PageETO<T>> GetShowQueryableAsync(int pageSize, int pageIndex)
        {
            PageETO<T> pageETO = new PageETO<T>();
            var queryable = await Task.Run(() => _client.Queryable<T>());
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }

        public async Task<PageETO<T>> GetShowQueryableAsync(int pageSize, int pageIndex, Expression<Func<T, bool>> exception)
        {

            PageETO<T> pageETO = new PageETO<T>();
            var queryable = await Task.Run(() => _client.Queryable<T>().Where(exception));
            pageETO.TotalCount = queryable.Count();
            pageETO.PageCount = Convert.ToInt32(Math.Ceiling(queryable.Count() * 1.0 / pageSize));
            pageETO.Data = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return pageETO;
        }



    }
}
